package com.bsj.pay.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.util.Map;

/**
 * <p>
 * RestTemplate 的封装
 * </p>
 *
 * @author chhuean
 * @since 2022-08-14
 */
@Service
public class AppTemplateImpl implements AppTemplate {

    @Autowired
    private RestTemplate restTemplate;

    @Override
    public String post(String url, Map<String, Object> data, Map<String, String> header) {
        ResponseEntity<String> forEntity = postRes(url, data, header);
        return forEntity.getBody();
    }

    @Override
    public String post(String url, Map<String, Object> data, Map<String, String> header, Map<String, Object> query) {
        ResponseEntity<String> forEntity = postRes(url, data, header, query);
        return forEntity.getBody();
    }

    @Override
    public String postForm(String url, Map<String, Object> data, Map<String, String> header) {
        ResponseEntity<String> forEntity = postFormRes(url, data, header);
        return forEntity.getBody();
    }

    @Override
    public String postForm(String url, Map<String, Object> data, Map<String, String> header, Map<String, Object> query) {
        ResponseEntity<String> forEntity = postFormRes(url, data, header, query);
        return forEntity.getBody();
    }

    @Override
    public String get(String url, Map<String, Object> query, Map<String, String> header) {
        ResponseEntity<String> forEntity = getRes(url, query, header);
        return forEntity.getBody();
    }

    @Override
    public ResponseEntity<String> postRes(String url, Map<String, Object> data, Map<String, String> header) {

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        if (header != null && !header.isEmpty()) {
            headers.setAll(header);
        }
        HttpEntity<Map<String, Object>> request = new HttpEntity<>(data, headers);

        return restTemplate.postForEntity(url, request, String.class);
    }

    @Override
    public ResponseEntity<String> postRes(String url, Map<String, Object> data, Map<String, String> header, Map<String, Object> query) {

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        if (header != null && !header.isEmpty()) {
            headers.setAll(header);
        }


        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
        if (query != null && !query.isEmpty()) {
            for (Map.Entry<String, Object> e : query.entrySet()) {
                builder.queryParam(e.getKey(), e.getValue());
            }
        }

        HttpEntity<Map<String, Object>> request = new HttpEntity<>(data, headers);

        return restTemplate.postForEntity(builder.build().encode().toString(), request, String.class);
    }

    @Override
    public ResponseEntity<String> postFormRes(String url, Map<String, Object> data, Map<String, String> header) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        if (header != null && !header.isEmpty()) {
            headers.setAll(header);
        }

        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
        if (data != null) {
            for (Map.Entry<String, Object> entry : data.entrySet()) {
                params.add(entry.getKey(), entry.getValue());
            }
        }

        HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(params, headers);

        return restTemplate.postForEntity(url, request, String.class);
    }

    @Override
    public ResponseEntity<String> postFormRes(String url, Map<String, Object> data, Map<String, String> header, Map<String, Object> query) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        if (header != null && !header.isEmpty()) {
            headers.setAll(header);
        }


        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
        if (query != null && !query.isEmpty()) {
            for (Map.Entry<String, Object> e : query.entrySet()) {
                builder.queryParam(e.getKey(), e.getValue());
            }
        }

        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
        if (data != null) {
            for (Map.Entry<String, Object> entry : data.entrySet()) {
                params.add(entry.getKey(), entry.getValue());
            }
        }

        HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(params, headers);

        return restTemplate.postForEntity(builder.build().encode().toString(), request, String.class);
    }

    @Override
    public ResponseEntity<String> getRes(String url, Map<String, Object> query, Map<String, String> header) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        if (header != null && !header.isEmpty()) {
            headers.setAll(header);
        }

        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
        if (query != null && !query.isEmpty()) {
            for (Map.Entry<String, Object> e : query.entrySet()) {
                builder.queryParam(e.getKey(), e.getValue());
            }
        }

        HttpEntity<Map<String, Object>> request = new HttpEntity<>(null, headers);

        return restTemplate.exchange(builder.build().encode().toUri(), HttpMethod.GET, request, String.class);
    }
}
